#include "chaineChaineEntree.h"

int chaineChaineEntreeNodeEstNull (pChaineChaineEntreeNode node)
{
	return node == NULL;
}

pChaineChaineEntreeNode nextChaineChaineEntreeNode(pChaineChaineEntreeNode node)
{
	if(chaineChaineEntreeNodeEstNull(node))
	{
		printf("Erreur : nextChaineChaineEntreeNode : node null;\n");
		exit(-1);
	}
	return node->next;
}

char * clefChaineChaineEntreeNode(pChaineChaineEntreeNode node)
{
	if(chaineChaineEntreeNodeEstNull(node))
	{
		printf("Erreur : clefChaineChaineEntreeNode : node null;\n");
		exit(-1);
	}
	return node->clef;
}

pChaineEntreeNode cibleChaineChaineEntreeNode(pChaineChaineEntreeNode node)
{
	if(chaineChaineEntreeNodeEstNull(node))
	{
		printf("Erreur : cibleChaineChaineEntreeNode : node null;\n");
		exit(-1);
	}
	return node->cible;
}

pChaineChaineEntreeNode nouveauChaineChaineEntreeNode (char * clef, pChaineEntreeNode cible)
{
	pChaineChaineEntreeNode node = malloc(sizeof(struct chaineChaineEntreeNode));
	node->clef = clef;
	node->cible = cible;
	node->next = NULL;
	return node;
}

int cmpChaineChaineEntreeNodeClef(char * clef, pChaineChaineEntreeNode node)
{
	char * nodeClef = clefChaineChaineEntreeNode(node);
	
	return strcmp(nodeClef,clef) == 0;
}

pChaineEntreeNode rechercheCibleChaineChaineEntreeNode(char * clef, pChaineChaineEntreeNode chaine)
{
	if(chaineChaineEntreeNodeEstNull(chaine))
	{
		printf("rechercheCibleChaineChaineEntreeNode : %s n'appartient pas à la chaine.\n",clef);
		return NULL;
	}
	
	if(cmpChaineChaineEntreeNodeClef(clef,chaine))
	{
		return cibleChaineChaineEntreeNode(chaine);
	} 
		
	return rechercheCibleChaineChaineEntreeNode(clef, nextChaineChaineEntreeNode(chaine));
}

int existeChaineChaineEntreeNodeCibleNonNull(char *clef, pChaineChaineEntreeNode chaine)
{
	if(chaineChaineEntreeNodeEstNull(chaine))
	{
		return 0;
	}

	if(cmpChaineChaineEntreeNodeClef(clef,chaine))
	{
		return !(valeurChaineEntreeNode(cibleChaineChaineEntreeNode(chaine)).idFantome);
	}
		
	return existeChaineChaineEntreeNode(clef, nextChaineChaineEntreeNode(chaine));
}

int existeChaineChaineEntreeNode(char *clef, pChaineChaineEntreeNode chaine)
{
	if(chaineChaineEntreeNodeEstNull(chaine))
	{
		return 0;
	}

	if(cmpChaineChaineEntreeNodeClef(clef,chaine))
	{
		return 1;
	}
		
	return existeChaineChaineEntreeNode(clef, nextChaineChaineEntreeNode(chaine));
}

pChaineChaineEntreeNode ajoutChaineChaineEntreeNodeDebut(char * clef, pChaineEntreeNode cible, pChaineChaineEntreeNode chaine)
{
	if(existeChaineChaineEntreeNode(clef,chaine))
	{
		printf("Erreur : ajoutChaineChaineEntreeNodeDebut : la clef existe ddeja dans la chaine.\n");
		exit(-1);
	}
	
	pChaineChaineEntreeNode nouveauNode = nouveauChaineChaineEntreeNode(clef,cible);
	nouveauNode->next = chaine;
	return nouveauNode;
}

pChaineChaineEntreeNode suppressionChaineChaineEntreeNode (char * clef, pChaineChaineEntreeNode chaine)
{//suppose que le hash node existe
	if(chaineChaineEntreeNodeEstNull(chaine))
	{
		printf("Erreur : suppressionChaineChaineEntreeNode : chaine vide.\n");
		exit(-1);
	}
	
	if(cmpChaineChaineEntreeNodeClef(clef,chaine))
	{
		return nextChaineChaineEntreeNode(chaine);
	}
	
	chaine->next = suppressionChaineChaineEntreeNode(clef, nextChaineChaineEntreeNode(chaine));
	return chaine;
}

int modifierCibleChaineChaineEntreeNode(char * clef, pChaineEntreeNode cible, pChaineChaineEntreeNode chaine)
{
	if(chaineChaineEntreeNodeEstNull(chaine))
	{
		printf("modifierCibleChaineChaineEntreeNode : %s n'appartient pas à la chaine.\n",clef);
		return -1;
	}
	
	if(cmpChaineChaineEntreeNodeClef(clef,chaine))
	{
		chaine->cible = cible;
		return 0;
	} 
		
	return modifierCibleChaineChaineEntreeNode(clef, cible, nextChaineChaineEntreeNode(chaine));
}

void afficheChaineChaineEntree (pChaineChaineEntreeNode chaine)
{
	pChaineEntreeNode node;
	entree element;
	char * clef;
	char * elementString;
	if(chaineChaineEntreeNodeEstNull(chaine))
	{
		printf("Chaine vide\n");
		return;
	}
	
	do
	{
		clef = clefChaineChaineEntreeNode(chaine);
		node = cibleChaineChaineEntreeNode(chaine);
		if(node!= NULL)
		{
			element = valeurChaineEntreeNode(node);
			elementString = entreeToString(element);
			printf("(%s,%s) ", clef, elementString);
		}
		else
		{
			printf("(%s,/) ", clef);
		}
		chaine = nextChaineChaineEntreeNode(chaine);
	}	
	while(!chaineChaineEntreeNodeEstNull(chaine));
	printf("\n");
}
